package com.shioirikukuri.common.web;

import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;

/**
 * 通用的响应结果封装类。
 *
 * 该类用于封装API调用的结果，包括状态码、消息和数据三部分。
 * 状态码用来标识请求处理的状态（成功或失败）；消息是对状态的文本描述；
 * 数据则包含了请求返回的具体内容。
 *
 * @param <T> 泛型，表示可能返回的数据类型。
 */
@Setter
@Getter
public class Result<T> implements Serializable {

    /** 成功的状态码 */
    public static final int SUCCESS_CODE = 200;

    /** 成功时的消息 */
    public static final String SUCCESS_MESSAGE = "操作成功";

    /** 错误的状态码 */
    public static final int ERROR_CODE = 500000;

    /** 发生错误时的默认消息 */
    public static final String ERROR_MESSAGE = "系统异常";

    /**
     * 响应的状态码
     */
    private int code;

    /**
     * 响应的消息
     */
    private String msg;

    /**
     * 响应的数据体
     */
    private T data;

    // 默认构造函数，允许通过setter方法设置属性值。
    public Result() {}

    /**
     * 私有构造函数，防止外部直接实例化对象，只能通过静态工厂方法创建。
     *
     * @param code   响应的状态码
     * @param msg    响应的消息
     * @param data   响应的数据体
     */
    private Result(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    /**
     * 创建一个成功的响应，不包含任何数据。
     *
     * @return 返回一个成功的响应结果
     */
    public static <T> Result<T> success() {
        return new Result<>(SUCCESS_CODE, SUCCESS_MESSAGE, null);
    }

    /**
     * 创建一个成功的响应，并包含给定的数据。
     *
     * @param data 要包含在响应中的数据
     * @return 返回一个成功的响应结果，其中包含提供的数据
     */
    public static <T> Result<T> success(T data) {
        return new Result<>(SUCCESS_CODE, SUCCESS_MESSAGE, data);
    }

    /**
     * 创建一个成功的响应，使用自定义消息并包含给定的数据。
     *
     * @param msg   自定义的成功消息
     * @param data  要包含在响应中的数据
     * @return 返回一个成功的响应结果，其中包含提供的数据和自定义消息
     */
    public static <T> Result<T> success(String msg, T data) {
        return new Result<>(SUCCESS_CODE, msg, data);
    }

    /**
     * 创建一个错误的响应，根据给定的CodeMsg对象。
     *
     * @param codeMsg 包含错误代码和消息的对象
     * @return 返回一个错误的响应结果
     */
    public static Result error(CodeMsg codeMsg) {
        return new Result(codeMsg.getCode(), codeMsg.getMsg(), null);
    }

    /**
     * 创建一个默认错误的响应。
     *
     * @return 返回一个带有默认错误信息的响应结果
     */
    public static Result defaultError() {
        return new Result(ERROR_CODE, ERROR_MESSAGE, null);
    }

    /**
     * 检查当前响应是否包含错误。
     *
     * @return 如果状态码不是成功码，则返回true，否则返回false
     */
    public boolean hasError() {
        // 如果状态码不等于成功码，则说明有错误发生。
        return this.code != SUCCESS_CODE;
    }
}
